package com.caration.shell.cr3d.a;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

public class ReflectHelper {
	private HashMap<String, HashMap<Object, MethodObject>> mEvents = new HashMap<String, HashMap<Object, MethodObject>>();

	public final void invoke(String name) {
		invoke(name, null);
	}

	public final void putEvent(String name, Object classObject,
			String methodName, Object[] args) {
		if (!mEvents.containsKey(name)) {
			HashMap<Object, MethodObject> hashMap = new HashMap<Object, MethodObject>();
			hashMap.put(classObject, new MethodObject(methodName, args));
			mEvents.put(name, hashMap);
		} else {
			mEvents.get(name).put(classObject,
					new MethodObject(methodName, args));
		}
	}

	public final void invoke(String name, ParameterObject[] objects) {
		if (!mEvents.containsKey(name)) {
			return;
		}

		MethodObject method = null;
		for (Iterator<Entry<Object, MethodObject>> iterator = mEvents.get(name)
				.entrySet().iterator(); iterator.hasNext();) {
			Entry<Object, MethodObject> entry = iterator.next();
			Object key = entry.getKey();
			method = entry.getValue();
			Class<?> parameterTypes[] = null;
			Object args[] = null;
			if (objects != null) {
				int length = objects.length;
				parameterTypes = new Class[length];
				args = new Object[length];
				for (int j = 0; j < length; j++) {
					ParameterObject object = objects[j];
					parameterTypes[j] = object.mParamType;
					args[j] = object.mValue;
					object.clear();
				}
			}
			try {
				key.getClass().getMethod(method.mMethodName, parameterTypes)
						.invoke(key, args);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}

			// int k = method.mParams.length;
			// Class[] arrayOfClass = new Class[k];
			// for (int i = 0; i < k; i++) {
			// arrayOfClass[i] = method.mParams[i].getClass();
			// }
			// key.getClass().getMethod(method.mMethodName, arrayOfClass)
			// .invoke(key, method.mParams);
		}
	}

	final class ParameterObject {
		public Object mValue;
		public Class<?> mParamType;

		public ParameterObject(Object value, Class<?> paramType) {
			mValue = value;
			mParamType = paramType;
		}

		public void clear() {
			mValue = null;
			mParamType = null;
		}
	}

	final class MethodObject {
		public String mMethodName;
		public Object[] mParams;

		public MethodObject(String name, Object[] params) {
			mMethodName = name;
			mParams = params;
		}
	}
}
